package cn.iocoder.yudao.module.system.service.portal;


import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.portal.vo.PortalDeptRespVO;
import cn.iocoder.yudao.module.system.controller.admin.portal.vo.PortalUserPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.portal.vo.PortalUserRespVO;
import cn.iocoder.yudao.module.system.controller.admin.portal.vo.PortalUserSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.nodeconfig.NodeConfigDO;
import cn.iocoder.yudao.module.system.dal.dataobject.portal.PortalUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.portal.PortalUserMapper;
import cn.iocoder.yudao.module.system.enums.ProtalUserEnum;
import cn.iocoder.yudao.module.system.service.nodeconfig.NodeConfigService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


import cn.iocoder.yudao.framework.common.util.object.BeanUtils;



import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;


/**
 * 门户网站用户 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class PortalUserServiceImpl implements PortalUserService {

    private static final Logger log = LoggerFactory.getLogger(PortalUserServiceImpl.class);

    @Resource
    private PortalUserMapper userMapper;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private NodeConfigService nodeConfigService;
    @Resource
    private PortalDeptService deptService;

    @Override
    public Long createUser(PortalUserSaveReqVO createReqVO) {
        //判断用户名是否存在
        PortalUserDO user1 = userMapper.selectByUsername(createReqVO.getName());
        if (user1 != null) {
            throw new ServiceException(500, "该用户已存在");
        }
        // 插入
        PortalUserDO user = BeanUtils.toBean(createReqVO, PortalUserDO.class);
        user.setUserType(ProtalUserEnum.AUTO_INCREMENT_USER.getType());
        user.setDelFlag(ProtalUserEnum.NOT_DELETED.getType());
        user.setCreateTime(new Date());
        user.setModifyTime(new Date());
        user.setCreatorId(getLoginUserId().toString());
        user.setPassword(encodePassword(user.getPassword()));
        userMapper.insert(user);

        // 返回
        return user.getId();
    }

    @Override
    public void updateUser(PortalUserSaveReqVO updateReqVO) {
        // 更新
        PortalUserDO updateObj = BeanUtils.toBean(updateReqVO, PortalUserDO.class);
        updateObj.setModifyTime(new Date());
        userMapper.updateById(updateObj);
    }

    @Override
    public void deleteUser(Long id) {
        // 删除前校验是否存在
        PortalUserDO user = userMapper.selectById(id);
        if (user == null) {
            throw new ServiceException(500, "用户不存在，无法删除");
        }
        userMapper.deleteById(id);
    }

    @Override
    public void deleteUserListByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            log.warn("删除用户列表：传入的用户ID列表为空");
            return;
        }
        // 删除
        userMapper.deleteByIds(ids);
    }

    @Override
    public PortalUserDO getUser(Long id) {
        return userMapper.selectById(id);
    }

    @Override
    public PageResult<PortalUserDO> getUserPage(PortalUserPageReqVO pageReqVO) {
        return userMapper.selectPage(pageReqVO);
    }

    @Override
    public void updateUserPassword(Long id, String decryptedPassword) {
        if (id == null || StringUtils.isEmpty(decryptedPassword)) {
            throw new ServiceException(500, "用户ID和密码不能为空");
        }
        String encodedPassword = encodePassword(decryptedPassword);
        PortalUserDO portalUserDO = new PortalUserDO()
                .setId(id)
                .setPassword(encodedPassword)
                .setModifyTime(new Date());
        userMapper.updateById(portalUserDO);
    }

    /**
     * 对密码进行加密
     *
     * @param password 密码
     * @return 加密后的密码
     */
    private String encodePassword(String password) {
        if (StringUtils.isEmpty(password)) {
            throw new ServiceException(500, "加密密码不能为空");
        }
        return passwordEncoder.encode(password);
    }

    @Override
    public PortalUserDO getUserByUsername(String username) {
        if (StringUtils.isEmpty(username)) {
            log.warn("根据用户名查询用户：用户名为空");
            return null;
        }
        return userMapper.selectByUsername(username);
    }

    @Override
    public PortalUserDO getUserById(Long id) {
        if (id == null) {
            log.warn("根据ID查询用户：用户ID为空");
            return null;
        }
        return userMapper.selectById(id);
    }

    @Override
    public boolean validatePassword(String rawPassword, String encodedPassword) {
        if (StringUtils.isEmpty(rawPassword) || StringUtils.isEmpty(encodedPassword)) {
            log.warn("校验密码：原始密码或加密密码为空");
            return false;
        }
        return passwordEncoder.matches(rawPassword, encodedPassword);
    }

    @Override
    public void updateUserLoginInfo(Long id, String loginIp) {
        if (id == null || StringUtils.isEmpty(loginIp)) {
            throw new ServiceException(500, "用户ID和登录IP不能为空");
        }
        userMapper.updateLoginInfo(id, loginIp, LocalDateTime.now());
    }

    @Override
    public List<PortalUserRespVO> getUserList() {
        return userMapper.selectUserList();
    }

    @Override
    public void deleteAll() {
        QueryWrapper<PortalUserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_type", ProtalUserEnum.SYNC_USER.getType());
        userMapper.delete(queryWrapper);
    }

    @Override
    public void batchCreateUser(List<PortalUserDO> userList) {
        if (CollectionUtils.isEmpty(userList)) {
            log.warn("批量创建用户：传入的用户列表为空");
            return;
        }
        String defaultPassword = encodePassword("123456");
        Date dateNow = new Date();
        String creatorId = getLoginUserId().toString();

        // 统一设置用户默认属性
        for (PortalUserDO portalUserDO : userList) {
            portalUserDO.setUserType(ProtalUserEnum.SYNC_USER.getType());
            portalUserDO.setPassword(defaultPassword);
            portalUserDO.setDelFlag(ProtalUserEnum.NOT_DELETED.getType());
            portalUserDO.setCreateTime(dateNow);
            portalUserDO.setModifyTime(dateNow);
            portalUserDO.setCreatorId(creatorId);
        }

        userMapper.insertBatch(userList);
    }

    @Override
    public String getUserName(String auditor) {
        if (StringUtils.isEmpty(auditor)) {
            log.warn("获取用户名：审核人名称为空");
            return null;
        }
        return userMapper.getUserNameByName(auditor);
    }

    @Override
    public List<PortalUserDO> getKxList() {
        // 1. 解析审核人JSON数据（含deptCode）
        NodeConfigDO nodeConfig = nodeConfigService.getNodeByCode("DEPT_AUDIT");
        if (nodeConfig == null || StringUtils.isEmpty(nodeConfig.getAuditor())) {
            log.warn("获取Kx用户列表：DEPT_AUDIT节点配置为空或审核人JSON为空");
            return Collections.emptyList();
        }
        String auditorJsonStr = nodeConfig.getAuditor();

        // 解析JSON为Map（使用FastJSON）
        Map<String, AuditUserVO> auditUserMap;
        try {
            auditUserMap = JSON.parseObject(
                    auditorJsonStr,
                    new TypeReference<Map<String, AuditUserVO>>() {}
            );
        } catch (Exception e) {
            log.error("解析审核人JSON失败，JSON内容:{}", auditorJsonStr, e);
            return Collections.emptyList();
        }

        // 转换为带deptCode的AuditUserVO列表
        List<AuditUserVO> auditUserList = auditUserMap.entrySet().stream()
                .map(entry -> {
                    String deptCode = entry.getKey();
                    AuditUserVO vo = entry.getValue();
                    if (vo == null) {
                        log.warn("解析审核人列表：部门编码{}对应的审核人信息为空，创建默认对象", deptCode);
                        vo = new AuditUserVO();
                    }
                    vo.setDeptCode(deptCode);
                    return vo;
                })
                .collect(Collectors.toList());

        // 2. 部门列表转Map（部门编码→部门名称）
        List<PortalDeptRespVO> deptList = deptService.getDeptList();
        if (CollectionUtils.isEmpty(deptList)) {
            log.warn("获取Kx用户列表：部门列表为空");
            return Collections.emptyList();
        }
        Map<String, String> deptCodeToNameMap = deptList.stream()
                .filter(dept -> StringUtils.isNotEmpty(dept.getOrgCode()))
                .collect(Collectors.toMap(
                        PortalDeptRespVO::getOrgCode,
                        PortalDeptRespVO::getName,
                        (existing, replacement) -> {
                            log.warn("部门编码重复：{}，保留第一个部门名称", existing);
                            return existing;
                        }
                ));

        // 3. 用户列表转Map（用户名→用户信息）
        List<PortalUserRespVO> userList = getUserList();
        if (CollectionUtils.isEmpty(userList)) {
            log.warn("获取Kx用户列表：用户列表为空");
            return Collections.emptyList();
        }
        Map<String, PortalUserRespVO> userNameToUserMap = userList.stream()
                .filter(user -> StringUtils.isNotEmpty(user.getName()))
                .collect(Collectors.toMap(
                        PortalUserRespVO::getName,
                        Function.identity(),
                        (existing, replacement) -> {
                            log.warn("用户名重复：{}，保留第一个用户信息", existing.getName());
                            return existing;
                        }
                ));

        // 4. 关联数据并封装为PortalUserDO列表
        return auditUserList.stream()
                .filter(auditUser -> {
                    boolean isValid = auditUser != null
                            && StringUtils.isNotEmpty(auditUser.getAuditor())
                            && StringUtils.isNotEmpty(auditUser.getDeptCode());
                    if (!isValid) {
                        log.warn("过滤无效审核人信息：auditUser={}", auditUser);
                    }
                    return isValid;
                })
                .map(auditUser -> {
                    PortalUserRespVO user = userNameToUserMap.get(auditUser.getAuditor());
                    String orgName = deptCodeToNameMap.get(auditUser.getDeptCode());

                    PortalUserDO userDO = new PortalUserDO();
                    userDO.setName(Optional.ofNullable(user)
                            .map(PortalUserRespVO::getName)
                            .orElse(auditUser.getAuditor()));
                    userDO.setNickName(Optional.ofNullable(user)
                            .map(PortalUserRespVO::getNickName)
                            .orElse(null));
                    userDO.setOrgCode(auditUser.getDeptCode());
                    userDO.setOrgName(orgName);
                    userDO.setMobile(auditUser.getMobile());
                    userDO.setTelePhone(auditUser.getTelephone());
                    userDO.setDelFlag(ProtalUserEnum.NOT_DELETED.getType());
                    return userDO;
                })
                .collect(Collectors.toList());
    }

    /**
     * 审核人信息VO（静态内部类，解决JSON解析实例化错误）
     */
    @Data
    public static class AuditUserVO {
        private String deptCode; // 部门编码（由JSON的key填充）
        private String auditor;  // 审核人名称（对应JSON中的auditor字段）
        private String mobile;   // 手机号（对应JSON中的mobile字段）
        private String telephone;// 座机号（对应JSON中的telephone字段）
    }
}